今天來整理一下在p5.js中有關表格的操作
一般的表格資料,分成橫排是列 Row,直排是行 Column,每一個表格元素是 Cell,就是主要放資料的地方。
對照到DOM的 table元件,就是 tr -> row,td -> column,th -> head
在使用p5.Table的物件時,可以用Row及Column的概念來思考。
其中當作表頭列的元素,可以使用th,可以使文字改以粗體呈現。
列 row -> tr -> r -> y
行 column -> td -> c -> x
以座標的概念來看就是
(y, x) -> (r, c) -> (tr, td) -> (row, column) -> (列, 行) -> (橫排, 直排)
在p5.js中,先從loadTable()這個指令開始。
loadTable()用來載入 csv格式的檔案,不管是.csv檔,或是網路試讀取下來的資料,只要是由逗號作為分隔符號的一筆一筆的資料就可以來處理。
ironman_5547.csv 是準備載入的csv檔案
這是csv的原始資料
編號,標題,發佈日期,瀏覽數
1,D01_準備好需要的工具,2022-09-15,165
2,D02_基本繪圖指令,2022-09-16,68
3,D03_Canvas畫布的密技,2022-09-17,122
4,D04_Canvas的圖像核心,2022-09-18,72
5,D05_Canvas的圖像畫素,2022-09-19,100
6,D06_Canvas的外部操作,2022-09-20,78
7,D07_Video元件的基本操作,2022-09-21,119
8,D08_Video元件的Capture操作,2022-09-22,61
9,D09_Video元件的YouTube影片操作,2022-09-23,114
10,D10_Graphics圖層操作,2022-09-24,126
let table;
function setup() {
table = loadTable("assets/ironman_5547.csv", "csv", "header", (result)=>{
console.log(result);
});
}
用console.log()查看的結果是,建立一個 Table的物件
從回傳的資料可以看到 column有4行,同時也是表頭的4個元素,row有10列,代表有10筆資料
接下來就是將資料以DOM table的元件呈現在網頁中,同時p5.Table物件本身也可以當作是一個小的資料庫來操作。
HTML
<body>
<div id="table1"></div>
</body>
CSS
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
JS
let table;
function setup() {
table = loadTable("assets/ironman_5547.csv", "csv", "header", (result)=>{
console.log(result.columns);
let head1 = result.columns;
let str = "<table>";
str += "<tr>";
for (let i = 0; i < table.getColumnCount(); i++){
str += "<th>"+head1[i]+"</th>";
}
str += "</tr>";
for (let r = 0; r < table.getRowCount(); r++){
str += "<tr>";
for (let c = 0; c < table.getColumnCount(); c++) {
console.log(table.getString(r, c));
str += "<td>"+table.getString(r, c)+"</td>";
}
str += "</tr>";
}
str += "</table>";
select("#table1").html(str);
});
}
在p5.Table中,每一個row是一個p5.TableRow的物件,
提供了一些關於row的操作
getRowCount(): row的列數
clearRows(): 刪除所有的row
addRow(row): 新增一列
removeRow(id): 移除編號id的列
getRow(rowID) -> TableRow 取得編號id的列
getRows() -> TableRow[] 取得所有的row
findRow(value, column) -> TableRow 取得在column中有符合value的列
findRows(value, column) -> TableRow[] 取得在column中有符合value的所有列
matchRow(regexp, column) -> TableRow 取得在column中有符合regexp的列
matchRows(regexp, column) -> TableRow[] 取得在column中有符合regexp的所有列
getColumnCount(): column的列數
getColumn(columnName): 取得欄位名稱columnName的column
addColumn(columnName): 新增一個欄位名稱為columnName的欄位
removeColumn(columnName): 移除欄位名稱columnName的column
trim(): 移除表格資料中,多餘的空白字元。
removeTokens(chars, columnName): 移除在columnName中的chars字元
set(rowID, columnID, value): 設定value給第rowID列,第columnID行的元素內容
setNum(rowID, columnID, value): 設定數值value給第rowID列,第columnID行的元素內容
setString(rowID, columnID, value): 設定文字value給第rowID列,第columnID行的元素內容
get(rowID, columnID): 設定第rowID列,第columnID行的元素內容
getNum(rowID, columnID): 設定第rowID列,第columnID行的數值元素內容
getString(rowID, columnID): 設定第rowID列,第columnID行的文字元素內容
getObject(): 取得整個表格的資料內容,以物件格式回傳。
getArray(): 取得整個表格的資料內容,以陣列格式回傳。
saveTable(Table, filename, options): 儲存表格資料到csv檔,經測試發現在存檔的時候會造成網頁重整,如果saveTable()寫在setup()的話,會變成網頁無窮的存檔,要注意!建議寫在click事件中來saveTable(),不過會造成網頁重整的問題,對於網頁的操作不是很好,最好是可以在背景中運作。
以下是新增一列資料的語法
let newRow = table.addRow();
newRow.setString('編號', table.getRowCount());
newRow.setString('標題', 'D11_文字與字型操作');
newRow.setString('發佈日期', '2022-09-25');
newRow.setString('瀏覽數', '58');
這是示範的程式碼
let table;
function setup() {
table = loadTable("assets/ironman_5547.csv", "csv", "header", (result)=>{
//console.log(result.columns);
//console.log(result.rows);
let newRow = table.addRow();
newRow.setString('編號', table.getRowCount());
newRow.setString('標題', 'D11_文字與字型操作');
newRow.setString('發佈日期', '2022-09-25');
newRow.setString('瀏覽數', '58');
let head1 = result.columns;
let str = "<table>";
str += "<tr>";
for (let i = 0; i < table.getColumnCount(); i++){
str += "<th>"+head1[i]+"</th>";
}
str += "</tr>";
for (let r = 0; r < table.getRowCount(); r++){
str += "<tr>";
for (let c = 0; c < table.getColumnCount(); c++) {
//console.log(table.getString(r, c));
str += "<td>"+table.getString(r, c)+"</td>";
}
str += "</tr>";
}
str += "</table>";
select("#table1").html(str);
console.log("table.getRowCount(): "+table.getRowCount());
console.log(table.getRows());
table.addColumn("名稱");
let rows = table.getRows();
for (let r = 0; r < rows.length; r++) {
rows[r].set('名稱', 'Unicorn'+r);
}
console.log(table.getRows());
console.log(table.getColumnCount());
console.log(table.getColumn('標題'));
console.log(table.getObject());
console.log(table.getArray());
});
select("#table1").mouseClicked( () => {
saveTable(table, 'assets/ironman_5547_1.csv', 'csv');
});
}
建議儲存檔案還是要以傳送到server端來處理。
原則上,p5.Table的作用,可以給下載表格檔案或是資料時,提供一個像是資料庫一般的資料處理功能。
若有新增,刪除,修改的資料,仍要以上傳到網站主機去更新資料為主。
參考資料
loadTable()
https://p5js.org/reference/#/p5/loadTable
p5.Table
https://p5js.org/reference/#/p5.Table
saveTable()
https://p5js.org/reference/#/p5/saveTable